nice_things/collections/Map.sh
The Map class implements a Hash Map in pure POSIX sh. This data structure is optimized for random access over iteration. The API is influenced by JavaScript Maps.
Being a class, while working with Map, you will be passing references around. The internal state of the object is managed by the framework's object system, you only have to keep a reference to it. The constructor returns a reference, and every method is this class take that reference as the first argument. The user is responsible for calling the Map_destructor method to free the resources used by the object.
By default, the order of insertion of keys is not preserved. An alternative Map_ordered constructor function exists for creating a Map that preserves the order of insertions, but note that all methods are slower when a Map is ordered.
Usage examples
# Create a Map: letters={a=1,b=2}
letters=#{{{ new Map }}} a 1 b 2
# Add mappings to the Map: letters={a=1,b=2,c=3,d=4}
Map_set "$letters" c 3 d 4
# Get the values of mappings "b" and "c": value_b=2 value_c=3
Map_get "$letters" value_b b value_c c
# Destroy the Map
Map_destructor "$letters"
Map
Since 0.3.0 · Source
import "{ Map }" from nice_things/collections/Map.sh
SynopsisMap <&self> [<key> <value>]…
Configuration
–
Description
Constructor for the unordered version of the Map class. Can optionally take initial mappings as arguments in the form of <key> <value> pairs.
By default, the order of insertion of keys is not preserved. An alternative Map_ordered constructor function exists for creating a Map that preserves the order of insertions, but note that all methods are slower when a Map is ordered.
Usually, this constructor function should be invoked with the new macro, which takes care of creating the <&self> reference to the newly created object.
Options
–
Operands
<&self>: Self reference.<key>: Key for a new mapping.<value>: Value of new mapping.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Successful completion.12: Invalid self reference<&self>(abort).
Abort
Aborts if self reference <&self> is invalid.
Usage examples
numbers=#{{{ new Map }}} 1 one 2 two 3 three 4 four 5 five
Map_clear
Since 0.3.0 · Source
import "{ Map_clear }" from nice_things/collections/Map_clear.sh
SynopsisMap_clear <&self>
Configuration
–
Description
Delete all mappings and set size to 0.
Options
–
Operands<&self>: Self reference.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Successful completion.12: Invalid self reference<&self>(abort).
Abort
Aborts if self reference <&self> is invalid.
Usage examples
Map_clear "$map"
Map_clone
Since 0.3.0 · Source
import "{ Map_clone }" from nice_things/collections/Map_clone.sh
SynopsisMap_clone <&self> <out_var>
Configuration
–
Description
Clone the Map. The new Map is assigned to <out_var>.
Options
–
Operands
<&self>: Self reference.<out_var>: Output variable; the result will be written to this variable.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Successful completion.12: Invalid self reference<&self>(abort).
Abort
Aborts if self reference <&self> is invalid.
Usage examples
Map_clone "$map" clone
Map_delete
Since 0.3.0 · Source
import "{ Map_delete }" from nice_things/collections/Map_delete.sh
SynopsisMap_delete <&self> <out_var> <key>
Configuration
–
Description
Delete the mapping identified by <key>. The deleted value is assigned to <out_var>.
Warning
Deleting keys of a
Map_orderedis extremely slow, and should generally not be done unless the object has very few mappings. An unorderedMaphave much more predictable performance, and can delete keys in nearly constant time.
Options
–
Operands
<&self>: Self reference.<out_var>: Output variable; the deleted value will be written to this variable. You can set this to the null string if you don't need the deleted value.<key>: Key of mapping to delete.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Successful completion.1:<key>does not exist in theMap.12: Invalid self reference<&self>(abort).
Abort
Aborts if self reference <&self> is invalid.
Usage examples
numbers=#{{{ new Map }}} 1 one 2 two 3 three 4 four 5 five
Map_delete "$numbers" deleted 3
log_debug "Deleted value: '${deleted}'" # three
Map_destructor
Since 0.3.0 · Source
import "{ Map_destructor }" from nice_things/collections/Map_destructor.sh
SynopsisMap_destructor <&self>
Configuration
–
Description
Clear all data associated with the object.
Options
–
Operands<&self>: Self reference.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Successful completion.12: Invalid self reference<&self>(abort).
Abort
Aborts if self reference <&self> is invalid.
Usage examples
Map_destructor "$map"
Map_get
Since 0.3.0 · Source
import "{ Map_get }" from nice_things/collections/Map_get.sh
SynopsisMap_get <&self> [<out_var> <key>]…
Configuration
–
Description
Get values from the Map by key.
Multiple values can be retrieved with a single invocation. If any <key> does not exist in the Map, status code 1 will be returned and the variable named by its <out_var> argument will be unset.
Options
–
Operands
<&self>: Self reference.<out_var>: Output variable; the value will be written to this variable.<key>: Key of the value to retrieve.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Successful completion.1: One or more<key>does not exist in theMap.12: Invalid self reference<&self>(abort).
Abort
Aborts if self reference <&self> is invalid.
Usage examples
numbers=#{{{ new Map }}} 1 one 2 two 3 three 4 four 5 five
if Map_get "$numbers" value 3; then
log_debug "Got value: '${value}'" # three
else
log_debug "Mapping '3' does not exist"
fi
Map_has
Since 0.3.0 · Source
import "{ Map_has }" from nice_things/collections/Map_has.sh
SynopsisMap_has <&self> <key>
Configuration
–
Description
Test if <key> exists in the Map. Return status code 0 if true, 1 if false.
Options
–
Operands
<&self>: Self reference.<key>: The key to search.
Stdin
–
Stdout
–
Stderr
–
Exit status
0:<key>exists in theMap.1:<key>does not exist in theMap.12: Invalid self reference<&self>(abort).
Abort
Aborts if self reference <&self> is invalid.
Usage examples
numbers=#{{{ new Map }}} 1 one 2 two 3 three 4 four 5 five
if Map_has "$numbers" 3; then
log_debug "'3' exists"
fi
Map_instance_of
Since 0.3.0 · Source
import "{ Map_instance_of }" from nice_things/collections/Map_class.sh
SynopsisMap_instance_of <&ref>
Configuration
–
Description
Check if <&ref> points to an instance of this class.
Returns status code 0 if <&ref> is a reference to an existing object of this class; otherwise, returns status code 1.
This method will also return status code 1 if <&ref> is not a valid reference, or if the object has already been destroyed.
Options
–
Operands<&ref>: The value to check.
Stdin
–
Stdout
–
Stderr
–
Exit status
0:<&ref>is an instance of this class.1:<&ref>is not an instance of this class.
Abort
–
Usage examples
if ! Map_instance_of "$object"; then
log_warn "The object is not an instance of this class"
fi
Map_keys
Since 0.3.0 · Source
import "{ Map_keys }" from nice_things/collections/Map_keys.sh
SynopsisMap_keys <&self> <out_var>
Configuration
–
Description
Get an Array containing all keys in the Map.
Useful for iterating over the mappings. Keys will be in insertion order if the Map is ordered—i.e., was created with the Map_ordered constructor.—If the Map is unordered—i.e., was created with the default Map constructor—the keys will be in the order of the hashes produced by the internal hash function, which is unpredictable and will usually look random.
Note
The user is responsible for calling the
Array_destructormethod to free the resources used by the keysArrayafter use.
Options
–
Operands
<&self>: Self reference.<out_var>: Output variable; a reference to theArraywill be written to this variable.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Successful completion.12: Invalid self reference<&self>(abort).123: Unexpected error (abort).
Abort
- Aborts if self reference
<&self>is invalid. - Aborts on unexpected error.
Usage examples
numbers=#{{{ new Map }}} 1 one 2 two 3 three 4 four 5 five
Map_keys "$numbers" keys
while Array_shift "$keys" key; do
Map_get "$numbers" value "$key"
# ...
done
Array_destructor "$keys"
Map_ordered
Since 0.3.0 · Source
import "{ Map_ordered }" from nice_things/collections/Map_ordered.sh
SynopsisMap_ordered <&self> [<key> <value>]…
Configuration
–
Description
Constructor for the ordered version of the Map class. Can optionally take initial mappings as arguments in the form of <key> <value> pairs.
Note
All methods are slower when the
Mapis ordered, especially theMap_deletemethod which is several times slower, and should generally not be used on aMap_orderedunless the object has very few mappings. If you don't need to preserve the order in which mappings are inserted, prefer the unordered version, by using the default constructor function:Map.
Usually, this constructor function should be invoked with the new macro, which takes care of creating the <&self> reference to the newly created object.
Options
–
Operands
<&self>: Self reference.<key>: Key for a new mapping.<value>: Value of new mapping.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Successful completion.12: Invalid self reference<&self>(abort).
Abort
Aborts if self reference <&self> is invalid.
Usage examples
numbers=#{{{ new Map_ordered }}} 1 one 2 two 3 three 4 four 5 five
Map_set
Since 0.3.0 · Source
import "{ Map_set }" from nice_things/collections/Map_set.sh
SynopsisMap_set <&self> [<key> <value>]…
Configuration
–
Description
Add mappings to the Map. Several mappings can be added with a single invocation.
Options
–
Operands
<&self>: Self reference.<key>: The key to add.<value>: The value to add.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Successful completion.12: Invalid self reference<&self>(abort).
Abort
Aborts if self reference <&self> is invalid.
Usage examples
numbers=#{{{ new Map }}} 1 one 2 two 3 three
Map_set "$numbers" 4 four 5 five
Map_size
Since 0.3.0 · Source
import "{ Map_size }" from nice_things/collections/Map_size.sh
SynopsisMap_size <&self> <out_var>
Configuration
–
Description
Get the size of the Map.
Options
–
Operands
<&self>: Self reference.<out_var>: Output variable; the result will be written to this variable.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Successful completion.12: Invalid self reference<&self>(abort).
Abort
Aborts if self reference <&self> is invalid.
Usage examples
numbers=#{{{ new Map }}} 1 one 2 two 3 three 4 four 5 five
Map_size "$numbers" size
log_debug "Numbers size: '${size}'" # 5
Map_to_quoted
Since 0.3.0 · Source
import "{ Map_to_quoted }" from nice_things/collections/Map_to_quoted.sh
SynopsisMap_to_quoted <&self> <out_var>
Configuration
–
Description
Get a quoted textual representation of the Map that is appropriate to use as an argument to the eval builtin command.
Note that this is a simple dump of the Map's internal state and currently does not preserve insertion order, even if the object was created with the Map_ordered constructor.
Options
–
Operands
<&self>: Self reference.<out_var>: Output variable; the result will be written to this variable.
Stdin
–
Stdout
–
Stderr
–
Exit status
0: Successful completion.12: Invalid self reference<&self>(abort).
Abort
Aborts if self reference <&self> is invalid.
Usage examples
Map_to_quoted "$map" quoted_map